using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Xml.Serialization;
using System.Diagnostics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;


namespace CoTuong
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public class Menu : Microsoft.Xna.Framework.DrawableGameComponent
    {
        #region Sprite, Texture, Position
        SpriteBatch spriteBatch;
        SpriteFont myFont;
        Texture2D menuTexture;
        Vector2 Menu_Position;

        Texture2D btnTaoVanCo;
        Vector2 btnTaoVanCo_Position;

        Texture2D btnExit;
        Vector2 btnExit_Position;

        Texture2D btnNapVanCo;
        Vector2 btnNapVanCo_Position;

        Texture2D btnHighScore;
        Vector2 btnHighScore_Position;

        Texture2D btnVersusLAN;
        Vector2 btnVersusLAN_Position;

        /*Texture2D btnPlayerVsNPC;
        Vector2 btnPlayerVsNPC_Position;*/

        Texture2D btnPlayerVsPlayer;
        Vector2 btnPlayerVsPlayer_Position;

        Texture2D btnHost;
        Vector2 btnHost_Position;

        Texture2D btnJoin;
        Vector2 btnJoin_Position;

        Texture2D btnBack;
        Vector2 btnBack_Position;
        #endregion

        #region Attributes Hover for Buttons
        bool isNewGameOnHover;
        bool isExitOnHover;
        bool isNapVanCoOnHover;
        bool isHighScoreOnHover;
        bool isBackOnHover;
        bool isPVPOnHover;
        bool isPVPLANOnHover;
        bool isHostOnHover;
        bool isJoinOnHover;
        #endregion
   
        #region Attributes for Load Game
        public enum typeLoadGame {Savedata, HighScoreData};
        IAsyncResult asyncResult;
        PlayerIndex playerIndex = PlayerIndex.One;
        StorageDevice device;
        StorageContainer container;
        String fileName;
        String HighScoreFileName;
        bool GameLoadRequested = false;
        bool isLoadFileOkay = false;
        bool isLoadHighScoreDataOkay = false;
        #endregion

        #region Commands
        public static bool CreateNewGame = false;
        public static bool LoadGame = false;
        public static bool ShowHighScore = false;
        public static bool CreateNetwork = false;
        #endregion

        bool isSelectedNewGame;
        bool isSelectedLAN;
        public static bool CreateHost = false;
        public static bool JoinGame = false;
        public static bool isHostNotFound;
        public static bool isWaitingForPlayer;
        public static bool CancelNetworkGame;

        public Menu(Game game)
            : base(game)
        {
            
        }

        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize()
        {
            
            asyncResult = Guide.BeginShowStorageDeviceSelector(playerIndex,
                        null, null);
            device = Guide.EndShowStorageDeviceSelector(asyncResult);
            container = device.OpenContainer("Co Tuong");

            //Lấy đường dẫn cho file bảng xếp hạng và ván đấu đã lưu
            string gamerTag = Gamer.SignedInGamers[PlayerIndex.One].Gamertag;
            fileName = Path.Combine(container.Path, gamerTag + ".sav");
            HighScoreFileName = Path.Combine(container.Path, "score.hs");

            //Kiểm tra file ván đấu đã lưu của người dùng
            if (File.Exists(fileName))
                isLoadFileOkay = true;

            //Kiểm tra tồn tại file bảng xếp hạng
            if (File.Exists(HighScoreFileName))
            {
                isLoadHighScoreDataOkay = true;
                //Nạp dữ liệu cho bảng xếp hạng
                doLoadHighScore();
            }

            //Kiểm tra người chơi mới
            if (isNewPlayer(gamerTag))
            {
                doSaveHighScore(gamerTag);
            }

            base.Initialize();
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(Game.GraphicsDevice);
            myFont = Game.Content.Load<SpriteFont>(@"Font\myFont");

            #region Load Images
            menuTexture = Game.Content.Load<Texture2D>(@"Images\menu");
            btnTaoVanCo = Game.Content.Load<Texture2D>(@"Images\Button\NewgameButton");
            btnExit = Game.Content.Load<Texture2D>(@"Images\Button\ExitButton");
            btnNapVanCo = Game.Content.Load<Texture2D>(@"Images\Button\LoadButton");
            btnHighScore = Game.Content.Load<Texture2D>(@"Images\Button\HighScoreButton");
            btnPlayerVsPlayer = Game.Content.Load<Texture2D>(@"Images\Button\PVP");
            btnVersusLAN = Game.Content.Load<Texture2D>(@"Images\Button\PVPLAN");
            btnHost = Game.Content.Load<Texture2D>(@"Images\Button\HostButton");
            btnJoin = Game.Content.Load<Texture2D>(@"Images\Button\JoinButton");
            btnBack = Game.Content.Load<Texture2D>(@"Images\Button\BackButton");
            #endregion

            #region Set Position
            Menu_Position.X = Game.Window.ClientBounds.Width / 2 - menuTexture.Width / 2;
            Menu_Position.Y = Game.Window.ClientBounds.Height / 2 - menuTexture.Height / 2;

            btnTaoVanCo_Position.X = Menu_Position.X + menuTexture.Width / 2 - btnTaoVanCo.Width / 2;
            btnTaoVanCo_Position.Y = Menu_Position.Y + menuTexture.Height / 5;

            btnExit_Position.X = Menu_Position.X + menuTexture.Width / 2 - btnExit.Width / 2;
            btnExit_Position.Y = Menu_Position.Y + menuTexture.Height - btnExit.Height * 5;

            btnNapVanCo_Position.X = Menu_Position.X + menuTexture.Width / 2 - btnNapVanCo.Width / 2;
            btnNapVanCo_Position.Y = Menu_Position.Y + menuTexture.Height / 3;

            btnHighScore_Position.X = Menu_Position.X + menuTexture.Width / 2 - btnHighScore.Width / 2;
            btnHighScore_Position.Y = Menu_Position.Y + menuTexture.Height / 2;

            btnPlayerVsPlayer_Position.X = Menu_Position.X + menuTexture.Width / 2 - btnPlayerVsPlayer.Width / 2;
            btnPlayerVsPlayer_Position.Y = Menu_Position.Y + menuTexture.Height / 5;

            btnVersusLAN_Position.X = Menu_Position.X + menuTexture.Width / 2 - btnVersusLAN.Width / 2;
            btnVersusLAN_Position.Y = Menu_Position.Y + menuTexture.Height / 3;

            btnHost_Position.X = Menu_Position.X + menuTexture.Width / 2 - btnHost.Width / 2;
            btnHost_Position.Y = Menu_Position.Y + menuTexture.Height / 5;

            btnJoin_Position.X = Menu_Position.X + menuTexture.Width / 2 - btnJoin.Width / 2;
            btnJoin_Position.Y = Menu_Position.Y + menuTexture.Height / 3;

            btnBack_Position.X = Menu_Position.X + menuTexture.Width / 2 - btnBack.Width / 2;
            btnBack_Position.Y = Menu_Position.Y + menuTexture.Height - btnBack.Height * 5;
            #endregion

            base.LoadContent();
        }

        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {
            try
            {

                #region Xử lý hơ chuột
                //Exit On Hover
                if (Game1.mousePosition.X > btnExit_Position.X && Game1.mousePosition.X < (btnExit_Position.X + btnExit.Width)
                    && Game1.mousePosition.Y > btnExit_Position.Y && Game1.mousePosition.Y < (btnExit_Position.Y + btnExit.Height))
                    isExitOnHover = true;
                else
                    isExitOnHover = false;

                //New game on Hover
                if (Game1.mousePosition.X > btnTaoVanCo_Position.X && Game1.mousePosition.X < (btnTaoVanCo_Position.X + btnTaoVanCo.Width)
                    && Game1.mousePosition.Y > btnTaoVanCo_Position.Y && Game1.mousePosition.Y < (btnTaoVanCo_Position.Y + btnTaoVanCo.Height))
                    isNewGameOnHover = true;
                else
                    isNewGameOnHover = false;

                //Load On Hover
                if (Game1.mousePosition.X > btnNapVanCo_Position.X && Game1.mousePosition.X < (btnNapVanCo_Position.X + btnNapVanCo.Width)
                    && Game1.mousePosition.Y > btnNapVanCo_Position.Y && Game1.mousePosition.Y < (btnNapVanCo_Position.Y + btnNapVanCo.Height))
                    isNapVanCoOnHover = true;
                else
                    isNapVanCoOnHover = false;

                //HighScore On Hover
                if (Game1.mousePosition.X > btnHighScore_Position.X && Game1.mousePosition.X < (btnHighScore_Position.X + btnHighScore.Width)
                    && Game1.mousePosition.Y > btnHighScore_Position.Y && Game1.mousePosition.Y < (btnHighScore_Position.Y + btnHighScore.Height))
                    isHighScoreOnHover = true;
                else
                    isHighScoreOnHover = false;

                if (Game1.mousePosition.X > btnBack_Position.X && Game1.mousePosition.X < (btnBack_Position.X + btnBack.Width)
                    && Game1.mousePosition.Y > btnBack_Position.Y && Game1.mousePosition.Y < (btnBack_Position.Y + btnBack.Height))
                    isBackOnHover = true;
                else
                    isBackOnHover = false;

                if (Game1.mousePosition.X > btnPlayerVsPlayer_Position.X && Game1.mousePosition.X < (btnPlayerVsPlayer_Position.X + btnPlayerVsPlayer.Width)
                    && Game1.mousePosition.Y > btnPlayerVsPlayer_Position.Y && Game1.mousePosition.Y < (btnPlayerVsPlayer_Position.Y + btnPlayerVsPlayer.Height))
                    isPVPOnHover = true;
                else
                    isPVPOnHover = false;

                if (Game1.mousePosition.X > btnVersusLAN_Position.X && Game1.mousePosition.X < (btnVersusLAN_Position.X + btnVersusLAN.Width)
                    && Game1.mousePosition.Y > btnVersusLAN_Position.Y && Game1.mousePosition.Y < (btnVersusLAN_Position.Y + btnVersusLAN.Height))
                    isPVPLANOnHover = true;
                else
                    isPVPLANOnHover = false;

                if (Game1.mousePosition.X > btnHost_Position.X && Game1.mousePosition.X < (btnHost_Position.X + btnHost.Width)
                    && Game1.mousePosition.Y > btnHost_Position.Y && Game1.mousePosition.Y < (btnHost_Position.Y + btnHost.Height))
                    isHostOnHover = true;
                else
                    isHostOnHover = false;

                if (Game1.mousePosition.X > btnJoin_Position.X && Game1.mousePosition.X < (btnJoin_Position.X + btnJoin.Width)
                    && Game1.mousePosition.Y > btnJoin_Position.Y && Game1.mousePosition.Y < (btnJoin_Position.Y + btnJoin.Height))
                    isJoinOnHover = true;
                else
                    isJoinOnHover = false;
                #endregion

                #region Xử lý click Thoát Game
                if (Game1.mouseClickedPosition.X > btnExit_Position.X && Game1.mouseClickedPosition.X < (btnExit_Position.X + btnExit.Width)
                    && Game1.mouseClickedPosition.Y > btnExit_Position.Y && Game1.mouseClickedPosition.Y < (btnExit_Position.Y + btnExit.Height)
                    && !isSelectedNewGame)
                {
                    //Thoát Game
                    Game.Exit();
                }
                #endregion

                #region Xử lý click tạo ván cờ mới
                if (Game1.mouseClickedPosition.X > btnTaoVanCo_Position.X && Game1.mouseClickedPosition.X < (btnTaoVanCo_Position.X + btnTaoVanCo.Width)
                    && Game1.mouseClickedPosition.Y > btnTaoVanCo_Position.Y && Game1.mouseClickedPosition.Y < (btnTaoVanCo_Position.Y + btnTaoVanCo.Height)
                    && !isSelectedNewGame)
                {
                    isSelectedNewGame = true;
                }

                else if (isSelectedNewGame)
                {
                    //Đã chọn phần tạo ván cờ mới, ta chọn chế độ chơi

                    //Chọn đấu trên cùng 1 máy
                    if (Game1.mouseClickedPosition.X > btnPlayerVsPlayer_Position.X && Game1.mouseClickedPosition.X < (btnPlayerVsPlayer_Position.X + btnPlayerVsPlayer.Width)
                        && Game1.mouseClickedPosition.Y > btnPlayerVsPlayer_Position.Y && Game1.mouseClickedPosition.Y < (btnPlayerVsPlayer_Position.Y + btnPlayerVsPlayer.Height)
                        && !isSelectedLAN)
                    {
                        CreateNewGame = true;
                    }

                    //Chọn đấu LAN
                    else if (Game1.mouseClickedPosition.X > btnVersusLAN_Position.X && Game1.mouseClickedPosition.X < (btnVersusLAN_Position.X + btnVersusLAN.Width)
                            && Game1.mouseClickedPosition.Y > btnVersusLAN_Position.Y && Game1.mouseClickedPosition.Y < (btnVersusLAN_Position.Y + btnVersusLAN.Height)
                            && !isSelectedLAN)
                    {
                        isSelectedLAN = true;
                    }

                    else if (isSelectedLAN)
                    {
                        //Đã chọn đấu LAN, ta chọn làm Host or Join

                        //Chọn Host
                        if (Game1.mouseClickedPosition.X > btnHost_Position.X && Game1.mouseClickedPosition.X < (btnHost_Position.X + btnHost.Width)
                            && Game1.mouseClickedPosition.Y > btnHost_Position.Y && Game1.mouseClickedPosition.Y < (btnHost_Position.Y + btnHost.Height)
                            && !CreateHost)
                        {
                            if (!CreateHost)
                                CreateNetwork = true;

                            CreateHost = true;
                            JoinGame = false;

                        }

                        //Join Host
                        else if (Game1.mouseClickedPosition.X > btnJoin_Position.X && Game1.mouseClickedPosition.X < (btnJoin_Position.X + btnJoin.Width)
                                 && Game1.mouseClickedPosition.Y > btnJoin_Position.Y && Game1.mouseClickedPosition.Y < (btnJoin_Position.Y + btnJoin.Height))
                        {
                            CreateNetwork = true;
                            JoinGame = true;
                            CreateHost = false;
                            isHostNotFound = false;
                        }
                    }
                }

                #endregion

                #region Xử lý nút Load Game
                if (Game1.mouseClickedPosition.X > btnNapVanCo_Position.X && Game1.mouseClickedPosition.X < (btnNapVanCo_Position.X + btnNapVanCo.Width)
                    && Game1.mouseClickedPosition.Y > btnNapVanCo_Position.Y && Game1.mouseClickedPosition.Y < (btnNapVanCo_Position.Y + btnNapVanCo.Height)
                    && !isSelectedNewGame)
                {
                    doLoadSave();
                }
                #endregion

                #region Xử lý nút Xem Xếp Hạng
                if (Game1.mouseClickedPosition.X > btnHighScore_Position.X && Game1.mouseClickedPosition.X < (btnHighScore_Position.X + btnHighScore.Width)
                    && Game1.mouseClickedPosition.Y > btnHighScore_Position.Y && Game1.mouseClickedPosition.Y < (btnHighScore_Position.Y + btnHighScore.Height)
                    && !isSelectedNewGame)
                {
                    ShowHighScore = true;
                }
                #endregion

                #region Xử lý nút Quay lại
                if (Game1.mouseClickedPosition.X > btnBack_Position.X && Game1.mouseClickedPosition.X < (btnBack_Position.X + btnBack.Width)
                    && Game1.mouseClickedPosition.Y > btnBack_Position.Y && Game1.mouseClickedPosition.Y < (btnBack_Position.Y + btnBack.Height))
                {
                    //Quay lại Menu chính (Thoát game, tạo ván đấu mới...)
                    if (isSelectedNewGame)
                        isSelectedNewGame = false;

                    //Quay lại màn hình chọn đấu LAN hoặc 2 người 1 máy
                    if (isSelectedLAN)
                    {
                        isSelectedLAN = false;
                        isSelectedNewGame = true;

                        if (isHostNotFound)
                        {
                            CancelNetworkGame = true;
                            CreateHost = false;
                            JoinGame = false;
                            isHostNotFound = false;
                        }

                        else if (NetworkGame.networkSession != null)
                        {
                            CancelNetworkGame = true;
                            CreateHost = false;
                            JoinGame = false;
                        }
                    }
                }

                #endregion
            }
            catch (Exception e)
            {
                Game1.errorMessage = e.Message;
            }
            base.Update(gameTime);
        }

        private void doLoadHighScore()
        {
            if (isLoadHighScoreDataOkay && !GameLoadRequested)
            {
                GameLoadRequested = true;
            }

            if ((GameLoadRequested) && (asyncResult.IsCompleted))
            {
                UpdateLoading((int)typeLoadGame.HighScoreData);
            }
        }
        
        private void UpdateLoading(int typeLoad)
        {
            
            if (device != null && device.IsConnected)
            {
                if (typeLoad == (int)typeLoadGame.Savedata)
                {
                    if (LoadData(device, typeLoad))
                        LoadGame = true;
                }

                else if(typeLoad == (int)typeLoadGame.HighScoreData)
                {
                    LoadData(device, typeLoad);    
                }
            }
        }

        private bool LoadData(StorageDevice device, int typeLoadData)
        {
            // Open the file.
            FileStream stream;
            if (typeLoadData == (int)typeLoadGame.Savedata)
                stream = File.Open(fileName, FileMode.Open, FileAccess.Read);
            else
                stream = File.Open(HighScoreFileName, FileMode.Open, FileAccess.Read);

            // Read the data from the file.
            XmlSerializer serializer;
            if (typeLoadData == (int)typeLoadGame.Savedata)
            {
                serializer = new XmlSerializer(typeof(SaveData));
                Game1.saveData = (SaveData)serializer.Deserialize(stream);
            }
            else
            {
                serializer = new XmlSerializer(typeof(HighScoreData));
                HighScoreData hsData = (HighScoreData)serializer.Deserialize(stream);
                HighScore.ListPlayer = hsData.listPlayerData;
            }
            stream.Close();

            container.Dispose();
            GameLoadRequested = false;
            return true;
            
        } 

        private void doLoadSave()
        {
            if (isLoadFileOkay && !GameLoadRequested)
            {
                GameLoadRequested = true;
            }

            if ((GameLoadRequested) && (asyncResult.IsCompleted))
            {
                UpdateLoading((int)typeLoadGame.Savedata);
            }
        }

        private void doSaveHighScore(string name)
        {
            if (asyncResult.IsCompleted)
                UpdateSaving(name);
        }

        private void UpdateSaving(string name)
        {
            if (device != null && device.IsConnected)
            {
                SaveHighScore(device, name);
            }
        }
 
        private void SaveHighScore(StorageDevice device, string playerName)
        {
            HighScoreData hsData = new HighScoreData();
            HighScore.ListPlayer.Add(new Player(playerName, 0, 0));
            hsData.listPlayerData = HighScore.ListPlayer;
            // Open a storage container.
            StorageContainer container = device.OpenContainer("Co Tuong");

            // Get the path of the save game.
            string filename = Path.Combine(container.Path, "score.hs");

            // Open the file, creating it if necessary.
            FileStream stream = File.Open(filename, FileMode.Create);

            // Convert the object to XML data and put it in the stream.
            XmlSerializer serializer = new XmlSerializer(typeof(HighScoreData));
            serializer.Serialize(stream, hsData);

            // Close the file.
            stream.Close();

            // Dispose the container, to commit changes.
            container.Dispose();
        }

        private bool isNewPlayer(string name)
        {
            foreach (Player p in HighScore.ListPlayer)
                if (p.Name.Equals(name))
                    return false;

            return true;
        }

        public override void Draw(GameTime gameTime)
        {
            Color myTransparentColor = new Color(255, 255, 255, 150);
            spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.None);
            spriteBatch.Draw(menuTexture, Menu_Position, Color.White);

            if (!isSelectedNewGame)
            {
                if (!isNewGameOnHover)
                    spriteBatch.Draw(btnTaoVanCo, btnTaoVanCo_Position, myTransparentColor);
                else
                    spriteBatch.Draw(btnTaoVanCo, btnTaoVanCo_Position, Color.White);

                if (!isExitOnHover)
                    spriteBatch.Draw(btnExit, btnExit_Position, myTransparentColor);
                else
                    spriteBatch.Draw(btnExit, btnExit_Position, Color.White);

                if (isNapVanCoOnHover && isLoadFileOkay)
                    spriteBatch.Draw(btnNapVanCo, btnNapVanCo_Position, Color.White);
                else
                    spriteBatch.Draw(btnNapVanCo, btnNapVanCo_Position, myTransparentColor);

                if (!isHighScoreOnHover)
                    spriteBatch.Draw(btnHighScore, btnHighScore_Position, myTransparentColor);
                else
                    spriteBatch.Draw(btnHighScore, btnHighScore_Position, Color.White);
            }

            else
            {
                if (!isSelectedLAN)
                {
                    if (isPVPOnHover)
                        spriteBatch.Draw(btnPlayerVsPlayer, btnPlayerVsPlayer_Position, Color.White);
                    else
                        spriteBatch.Draw(btnPlayerVsPlayer, btnPlayerVsPlayer_Position, myTransparentColor);

                    if (isPVPLANOnHover)
                        spriteBatch.Draw(btnVersusLAN, btnVersusLAN_Position, Color.White);
                    else
                        spriteBatch.Draw(btnVersusLAN, btnVersusLAN_Position, myTransparentColor);
                }
                else if (NetworkGame.networkSession == null)
                {
                    if (isHostOnHover)
                        spriteBatch.Draw(btnHost, btnHost_Position, Color.White);
                    else
                        spriteBatch.Draw(btnHost, btnHost_Position, myTransparentColor);

                    if (isJoinOnHover)
                        spriteBatch.Draw(btnJoin, btnJoin_Position, Color.White);
                    else
                        spriteBatch.Draw(btnJoin, btnJoin_Position, myTransparentColor);

                    if (isHostNotFound)
                        spriteBatch.DrawString(myFont, "Host not Found",
                            new Vector2(Game.Window.ClientBounds.Width / 2 - myFont.MeasureString("Host Not Found").X / 2,
                            Game.Window.ClientBounds.Height / 2), Color.White);

                }
                else if (NetworkGame.networkSession != null)
                {
                    spriteBatch.DrawString(myFont, "Waiting for other player connect",
                            new Vector2(Game.Window.ClientBounds.Width / 2 - myFont.MeasureString("Waiting for other player connect").X / 2,
                            Game.Window.ClientBounds.Height / 2), Color.White);
                }


                if (isBackOnHover)
                    spriteBatch.Draw(btnBack, btnBack_Position, Color.White);
                else
                    spriteBatch.Draw(btnBack, btnBack_Position, myTransparentColor);
            }

            spriteBatch.End();

            base.Draw(gameTime);
        }

    }
}